package com.qianfeng.vhly.youshare.view;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.GridView;

/**
 * Created with IntelliJ IDEA.
 * User: vhly[FR]
 * Date: 15/2/7
 * Email: vhly@163.com
 */

/**
 * 继承GridView，实现在ScrollView中能够完整显示的GridView,
 * 这种情况通常不推荐在ScrollView放 GridView和ListView，
 * 如果必须采用这种方式，那么就用自定义的GridView或者 ListView
 * 来实现，确保高度，但是，GridView或者ListView 的优化可能失效
 */
public class FullGridView extends GridView {

    // 1. 自定义View知识点1：构造方法，layout布局的引用

    /**
     * 构造方法，通用用于在代码中创建 View控件时，使用
     * 这个方法只能够在代码中创建View
     *
     * @param context
     */
    public FullGridView(Context context) {
        super(context);
    }

    /**
     * 如果一个自定义的View，需要放到 layout xml文件中，
     * 那么必须提供这个构造方法
     *
     * @param context
     * @param attrs
     */
    public FullGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    // 对于在 ScrollView中的 GridView，我们需要重写一个方法，onMeasure(int, int)

    /**
     * 本方法通常在，父容器Layout计算尺寸的时候，需要向子控件或者容器
     * 问一下子控件的大小，这个时候，子控件就要算一下自己到底有多大，
     * 然后返回给父容器，当子控件／子容器计算自己有多大的时候，会进行一个回调方法
     * 这个回调方法就是  onMeasure(int, int)方法，这个方法内部必须设置自身的尺寸
     * 这样父容器才知道有多大。
     *
     * @param widthMeasureSpec  宽度尺寸规格，宽度包含父容器允许控件最大有多宽
     * @param heightMeasureSpec 高度尺寸规格，高度规格里包含了父容器允许控件最大有多高，同时还有是 wrap_content 还是 确切的数值
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 获取宽度规格中的宽度数值
        int wSize = MeasureSpec.getSize(widthMeasureSpec);
        int wMode = MeasureSpec.getMode(widthMeasureSpec);

        // 获取宽度规格中的宽度数值
        int hSize = MeasureSpec.getSize(heightMeasureSpec);
        int hMode = MeasureSpec.getMode(heightMeasureSpec);

        // wSize, hSize 就是父容器给当前控件提供的最大的空间
        //              或者是在layout文件中，我们指定的数值尺寸，如 200dp
        //              实际获取的数值，单位是像素，如果布局采用dp，单位
        //              那么此处获取到的像素和布局写的数值可能会不同。
        Log.d("YouShare", "wSize=" + wSize);
        Log.d("YouShare", "hSize=" + hSize);

        // mode 代表了，尺寸计算的方式。
        // MeasureSpec 里面提供了尺寸计算模式的常量定义

        switch (hMode){
            case MeasureSpec.AT_MOST: // wrap_content
                Log.d("YouShare", "hMode = AT_MOST");
                break;
            case MeasureSpec.EXACTLY: // match_parent, xxxdp
                Log.d("YouShare", "hMode = EXACTLY");
                break;
            case MeasureSpec.UNSPECIFIED: // 未指定，不限定尺寸计算的方式。
                Log.d("YouShare", "hMode = UNSPECIFIED");
                break;
        }

        // 如果我们能够，把高度 hSize 设置一个很大的值，
        // 并且将尺寸计算模式，调整为AT_MOST(wrap_content)
        // 那么GridView将能够完全显示

        // 重新生成一个 int值，这个值通过MeasureSpec将 size 和 mode 组合
        // 就可以放GridView放大了

        heightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 1, MeasureSpec.AT_MOST);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}
